﻿using System;
using System.Threading.Tasks;
using SaaS.Model.Dto.Sites;
using SaaS.Model.Entity.Sites;
using XCore.Logger;
using System.Linq;
using System.Collections.Generic;
using XCore.Extensions;
using XCore.Domain;
using XCore.Dapper;
using XCore.Dependency;

namespace Web.System.Services.Sites
{
    public class ProjectAppService : SystemApplicationServiceBase, ITransientDependency
    {
        public int CreateOrEdit(ProjectInput input)
        {
            if (input.Id.HasValue)
            {
                if (input.Details != null)
                    foreach (var item in input.Details)
                        this.CreateOrEditDetail(item, input.Id.Value);
                Repository.Update<Project, ProjectInput>(input);
                return input.Id.Value;
            }
            else
            {
                var entity = ObjectMapper.Map<Project>(input);
                var projectId = Repository.InsertAndGetId(entity);
                if (input.Details != null)
                    foreach (var item in input.Details)
                        this.CreateOrEditDetail(item, projectId);
                return projectId;
            }
        }
        private bool CreateOrEditDetail(ProjectDetailInput input, int projectId)
        {
            if (input.Id.HasValue)
            {
                return Repository.Update<ProjectDetail, ProjectDetailInput>(input);
            }
            else
            {
                var entity = ObjectMapper.Map<ProjectDetail>(input);
                entity.ProjectId = projectId;
                return Repository.Insert(entity);
            }
        }

        public bool Delete(int id)
        {
            if (SDC.Projects.Any(c => c.Id == id && c.IsRelease))
                throw new MessageException("已发布产品不可删除");
            var projectDetailIds = SDC.ProjectDetails.Where(c => c.ProjectId == id).Select(c => c.Id);
            foreach (var item in projectDetailIds) Repository.Delete<ProjectDetail>(item);
            return Repository.Delete<Project>(id);
        }
        public Task<ProjectDto> GetInfoAsync(int id)
        {
            var entity = Repository.Get<Project, ProjectDto>(id);
            entity.Details = this.GetDetailList(entity.Id);
            return Task.FromResult(entity);
        }
        public IEnumerable<ProjectDetailDto> GetDetailList(int projectId)
        {
            return SDC.ProjectDetails.Where(c => c.ProjectId == projectId)
                .Select(c => new ProjectDetailDto()
                {
                    Discount = c.Discount,
                    Id = c.Id,
                    Month = c.Month,
                    Price = c.Price
                });
        }

        public bool ReleaseAsync(int id)
        {
            var release = SDC.Projects.Where(c => c.Id == id).Select(c => c.IsRelease).FirstOrDefault();
            Repository.Update<Project, bool>(id, c => c.IsRelease, !release);
            return !release;
        }
        public IEnumerable<string> GetPermissions(int id)
        {
            return SDC.ProjectPermissions.Where(c => c.ProjectId == id).Select(c => c.Name);
        }
        public void Authoriza(int id, string[] permissions)
        {
            Repository.Delete<ProjectPermission>(c => c.ProjectId == id);
            foreach (var item in permissions)
            {
                Repository.Insert(new ProjectPermission { ProjectId = id, Name = item });
            }
        }
    }
}
